package com.feng.yupaoback.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.feng.yupaoback.common.BaseResult;
import com.feng.yupaoback.common.ErrorCode;
import com.feng.yupaoback.common.ResultUtils;
import com.feng.yupaoback.constant.BaseConst;
import com.feng.yupaoback.exception.BusinessException;
import com.feng.yupaoback.mapper.UserMapper;
import com.feng.yupaoback.pojo.dto.UserLoginRequest;
import com.feng.yupaoback.pojo.dto.UserRegisterRequest;
import com.feng.yupaoback.pojo.dto.UserUpdateInfoRequest;
import com.feng.yupaoback.pojo.dto.UserUpdatePwdRequest;
import com.feng.yupaoback.pojo.entity.User;
import com.feng.yupaoback.pojo.vo.UserVO;
import com.feng.yupaoback.service.UserService;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Slf4j
@RestController
@RequestMapping("/user")
public class UserController {

    @Resource
    private UserService userService;

    @Resource
    private RedisTemplate<String,Object> myRedisTemplate;

    /**
     * 用户登录
     * @param userLoginRequest 登录体
     * @param request 请求
     * @return 用户信息（脱敏）
     */
    @PostMapping("/login")
    public BaseResult<User> userLogin(@RequestBody UserLoginRequest userLoginRequest, HttpServletRequest request) {
        if (userLoginRequest == null){
            throw new BusinessException(ErrorCode.NULL_ERROR, "请求数据为空");
        }

        // 基础校验（与业务无关）
        String userAccount = userLoginRequest.getUserAccount();
        String userPassword = userLoginRequest.getUserPassword();

        if (StringUtils.isAnyBlank(userAccount, userPassword)) {
            throw new BusinessException(ErrorCode.NULL_ERROR, "账户或密码为空！");
        }

        User user =  userService.userLogin(userAccount, userPassword, request);
        return ResultUtils.success(user);
    }

    /**
     * 退出登录
     * @param request 请求
     * @return 退出
     */
    @PostMapping("/logout")
    public BaseResult<Integer> userLogout(HttpServletRequest request) {
        if (request == null){
            throw new BusinessException(ErrorCode.NULL_ERROR, "请求为空！");
        }
        int result = userService.userLogout(request);
        return ResultUtils.success(result);
    }

    /**
     * 用户注册
     * @param userRegisterRequest 注册体
     * @return 用户id
     */
    @PostMapping("/register")
    public BaseResult<Long> userRegister(@RequestBody UserRegisterRequest userRegisterRequest) {
        if (userRegisterRequest == null){
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }

        // 基础校验（与业务无关）
        String userAccount = userRegisterRequest.getUserAccount();
        String userPassword = userRegisterRequest.getUserPassword();
        String checkPassword = userRegisterRequest.getCheckPassword();
        String planetCode = userRegisterRequest.getPlanetCode();

        if (StringUtils.isAnyBlank(userAccount, userPassword, checkPassword, planetCode)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }

        long result = userService.userRegister(userAccount, userPassword, checkPassword, planetCode);
        return ResultUtils.success(result);
    }

    /**
     * 当前状态
     * @param request 请求
     * @return 当前用户
     */
    @GetMapping("/current")
    public BaseResult<User> getCurrentUser(HttpServletRequest request) {
        User loginUser = userService.getCurrentUser(request);
        return ResultUtils.success(loginUser);
    }

    /**
     * 修改密码
     * @param userUpdatePwdRequest 修改密码请求体
     * @param request 请求
     * @return 修改状态
     */
    @PostMapping("/updatePwd")
    public BaseResult<Long> updatePwd(@RequestBody UserUpdatePwdRequest userUpdatePwdRequest, HttpServletRequest request) {
        if (userUpdatePwdRequest == null){
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "参数错误！");
        }
        String oldPwd = userUpdatePwdRequest.getOldPwd();
        String newPwd = userUpdatePwdRequest.getNewPwd();
        String checkPwd = userUpdatePwdRequest.getCheckPwd();

        if (StringUtils.isAnyBlank(oldPwd, newPwd, checkPwd)) {
            throw new BusinessException(ErrorCode.NULL_ERROR, "参数为空！");
        }
        long res = userService.updatePassword(oldPwd, newPwd, checkPwd, request);
        if (res != 1){
            throw new RuntimeException("系统错误");
        }
        return ResultUtils.success(res);
    }

    /**
     * 更新信息
     * @param userUpdateInfoRequest
     * @param request
     * @return
     */
    @PostMapping("/updateInfo")
    public BaseResult<User> updateInfo(@RequestBody UserUpdateInfoRequest userUpdateInfoRequest, HttpServletRequest request) {
        if (userUpdateInfoRequest == null){
            throw new BusinessException(ErrorCode.NULL_ERROR, "请求参数为空！");
        }
        User user = userService.updateInfo(userUpdateInfoRequest, request);
        return ResultUtils.success(user);
    }

    /**
     * 查询用户
     * @param username 用户昵称
     * @param request 请求
     * @return 用户信息
     */
    @GetMapping("/search")
    public BaseResult<List<User>> searchUsers(String username, HttpServletRequest request) {
        if (!userService.isAdmin(request)){
            throw new BusinessException(ErrorCode.NO_AUTH, "无管理员权限！");
        }

        List<User> list = userService.searchUsers(username);
        List<User> safetyUserist = list.stream().map(user -> {
            return userService.getSafetyUser(user);
        }).collect(Collectors.toList());
        return ResultUtils.success(safetyUserist);
    }

    /**
     * 删除用户
     * @param id 用户id
     * @param request 请求
     * @return 标志位
     */
    @PostMapping("/delete")
    public BaseResult<Boolean> deleteUser(@RequestBody long id, HttpServletRequest request) {
        if (!userService.isAdmin(request)){
            throw new BusinessException(ErrorCode.NO_AUTH, "无管理员权限！");
        }
        if (id <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "删除的id异常！");
        }

        boolean flag = userService.removeById(id);
        return ResultUtils.success(flag);
    }

    /**
     * 主页推荐用户
     * @param pageSize 页面大小
     * @param pageNum 页数
     * @param request 请求
     * @return 推荐的用户列表
     */
    @GetMapping("/recommend")
    public BaseResult<Page<User>> getRecommendUsers(long pageSize, long pageNum, HttpServletRequest request){
        // 先从缓存中查询数据，如果有直接返回，如果没有则查数据库
        int userId = userService.getCurrentUser(request).getId();
        String redisKey = String.format("yupao-recommend-user-%S", userId);
        ValueOperations<String, Object> valueOperations = myRedisTemplate.opsForValue();

        @SuppressWarnings("unchecked")
        Page<User> userList = (Page<User>) valueOperations.get(redisKey);
        if (userList != null){
            log.info("我从缓存中取数据啦！");
            return ResultUtils.success(userList);
        }
        // 走数据库
        log.info("我从数据库中取数据啦！");
        userList = userService.getRecommendUsers(pageSize, pageNum);
        try {
            valueOperations.set(redisKey, userList, 36000000,TimeUnit.MILLISECONDS);
        } catch (Exception e) {
            log.error(e.getMessage());
        }
        return ResultUtils.success(userList);
    }

    /**
     * 根据标签查询用户
     * @param tagNameList 标签列表
     * @return 符合要求的用户
     */
    @GetMapping("/search/tags")
    public BaseResult<List<User>> searchUserByTags(@RequestParam(required = false) List<String> tagNameList){
        if (CollectionUtils.isEmpty(tagNameList)){
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "标签列表为空");
        }
        List<User> userList = userService.searchUsersByTags(tagNameList);
        return ResultUtils.success(userList);
    }


    /**
     * 根据标签匹配用户
     * @param num 数量
     * @param request 请求
     * @return 用户列表
     */
    @GetMapping("/match")
    public BaseResult<List<User>> matchUsers(long num, HttpServletRequest request) {
        if (num <= 0 || num > 20){
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "数量过多！");
        }
        User loginUser = userService.getCurrentUser(request);
        return ResultUtils.success(userService.getMatchUsers(num, loginUser));
    }

}
